/* 
 *  Copyright 2012 CodeMagi, Inc.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.codemagi.taglibs.taxonomy;

import com.codemagi.servlets.model.*;
import com.codemagi.util.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.*;

/**
 * This class implements the &lt;tax:multiselect&gt; tag, which presents a select list to choose multiple taxonomy terms
 *
 *  @version 1.0
 *  @author August Detlefsen for CodeMagi, Inc.
 */
public class TaxonomyMultiSelect extends TaxonomyTag {

    public int doStartTag() throws JspException {

	// sanity check                                                                                                   
	if (categoryId == null) throw new JspTagException("invalid categoryId specified");

	//determine the name for the select list
	String name = "taxonomy_" + categoryId;

        try {
            // get what we need from the page                                                                                   
            ServletRequest req = pageContext.getRequest();
            JspWriter out = pageContext.getOut();

            // start building up the tag                                                                                          
            out.println();
            out.println("<select multiple=\"multiple\" ");
            out.println("    name=\"" + name + "\"");
            if (!Utils.isEmpty(id)) {
                out.println("    id=\"" + quote(id) + "\"");
            }

            //disable the form field if disabled is set                                                                
            if (disabled) {
                out.println("    readonly=\"readonly\"");
                out.println("    OnFocus=\"blur();\"");
                appendAttribute("style", "cursor:default;");
            }

            // include any attributes we've got here                                                                          
            printAttributes(out, attributes);

            //if this is a required field and it is not filled out, do something...                                 
            if ( !Utils.isEmpty((String)req.getAttribute("error_" + name + "_error")) ) {
                out.println("    class=\"" + markupClass + "_error\"");
            } else if ( !Utils.isEmpty(markupClass) ) {
                out.println("    class=\"" + markupClass + "\"");
            }

            // end the starting tag                                                                                           
            out.println(">");

            /*                                                                                                                  
             * Print out our options, selecting one or more if appropriate.                                                        
             */

            // get the current selection.                                                                                          
	    String[] selected = getParameterValues(name, (HttpServletRequest)req);
            log.debug("Select: selected: " + selected);
            log.debug("Select: (selected != null) = " + (selected != null));
            log.debug("Select: (selected != null && selected.length > 1) = " + (selected != null && selected.length > 1));
            log.debug("Select: (attributes == null) + " + (attributes == null));

            // load up the selected values into a hash table for faster access                
            // otherwise use defaults                                                                                 
            HashMap chosen = new HashMap();

            if (selected == null || override) {
                log.debug("Select: building chosen from Node");

                List selectedTerms = (node == null) ? new ArrayList<Term>() : node.getTerms(categoryId) ;

                Iterator e = selectedTerms.iterator();
                while (e.hasNext()) {
		    Term term = (Term)e.next();

                    chosen.put(term.getId() + "", null);
                }
            } else {
                log.debug("Select: building chosen from request");

                for (int i = 0; i < selected.length; i++) {
                    chosen.put(selected[i], null);
                }

            }

            // actually print the <option> tags                                                                                    
	    List options = category.getTerms();
	    Iterator i   = options.iterator();

	    while (i.hasNext()) {
		Term term = (Term)i.next();
		
		String key   = term.getId() + "";
		String value = term.getName();

		if (key == null) continue;  //do not allow null keys                                                    

		if (value == null) value = key;             // use key if value is null                                    

		out.print("<option value=\"" + key + "\"");

		//determine if this option should be selected                                                           
		if ( chosen.containsKey(key) ) out.print(" selected=\"selected\"");

		out.print(">");
		out.print(quote(value));
		out.println("</option>");
	    }

            // close off the surrounding select                                                                        
            out.println("</select>");

        } catch (Exception ex) {
            log.debug("", ex);
            throw new JspTagException(ex.getMessage());
        }
        return SKIP_BODY;
    }

}
